using System;
using System.Collections.Generic;
using System.IO;
using EnvDTE;
using SolutionFactory.Services;
using SolutionFactory.UI;
using SolutionFactory.VSTemplateSchema;
using ProjectItem=EnvDTE.ProjectItem;

namespace SolutionFactory.Exporter
{
    public class SolutionExporter
    {
        private const string PROJECTS_FOLDER_NAME = "projects";
        private const string SOLUTION_ITEMS_FOLDER_NAME = "solution-items";
        private readonly FileArchiveService _archiveService;
        private readonly FileCopyAndTokenReplacer _fileCopyAndTokenReplacer;
        private readonly InstallerCreationService _installerCreationService;

        private readonly IFileSystem _fileSystem;
        private readonly Logger _logger;
        private readonly IMessageBox _messageBox;
        private readonly VSTemplateFactory _templateFactory;

        public SolutionExporter(IFileSystem fileSystem, IMessageBox messageBox, IFileTokenReplacer fileTokenReplacer,
                                VSTemplateFactory templateFactory, Logger logger, FileArchiveService archiveService,FileCopyAndTokenReplacer fileCopyAndTokenReplacer,InstallerCreationService installerCreationService)
        {
            _fileSystem = fileSystem;
            _messageBox = messageBox;
            _templateFactory = templateFactory;
            _logger = logger;
            _archiveService = archiveService;
            _fileCopyAndTokenReplacer = fileCopyAndTokenReplacer;
            _installerCreationService = installerCreationService;
        }

        private void CreateContentPackage(TemplateInput model, string templateZipFilename)
        {
            string tempDirectory = _fileSystem.CreateTempDirectory();
            _templateFactory.CreateContentFile(templateZipFilename, model, tempDirectory);
            _fileSystem.Copy(templateZipFilename, tempDirectory.Combine(_fileSystem.GetFileNameWithExtension(templateZipFilename)));



            string directoryName = _fileSystem.GetDirectoryName(templateZipFilename);
            string fileName = directoryName.Combine("Template.vsi");

            _logger.Log("Creating Package " + fileName);
            _archiveService.ZipTemplate(tempDirectory, fileName);


            _fileSystem.Delete(tempDirectory);
            _logger.Log("Package " + fileName + " created.");
        }




        private TemplateParams GetTemplateParamsFromModel(TemplateInput model)
        {
            return new TemplateParams(model.Name, model.RunOnCompletion, model.Category,
                                      model.SubCategory, model.Description);
        }




        public void Export(Solution solution, TemplateInput model)
        {
            try
            {
                var templates = new List<VSTemplate>();
                var templateLinks = new List<ProjectTemplateLink>();

                string name = _fileSystem.GetFileName(solution.FileName);

                _fileCopyAndTokenReplacer.InitializeTokenReplacer(name);

                string dir = model.OutputDirectory.Combine(name);
                string solutionItemDir = dir.Combine(SOLUTION_ITEMS_FOLDER_NAME);
                string projectDestinationDirectory = dir.Combine(PROJECTS_FOLDER_NAME);

                _fileSystem.Delete(dir);

                _logger.Log("Copying Non-solution files");
                _fileCopyAndTokenReplacer.CopyNonSolutionFiles(solutionItemDir, solution);

				//_logger.Log("Copying Project Templates");
				//_templateFactory.CreateProjectTemplates(templateLinks, templates, projectDestinationDirectory, solution,PROJECTS_FOLDER_NAME);

				//_logger.Log("Copying Project Items");
				//_fileCopyAndTokenReplacer.CopyProjectsToDestinationFolder(projectDestinationDirectory, solution);

                TemplateParams templateParams = GetTemplateParamsFromModel(model);

                _logger.Log("Creating Solution Template");
                _templateFactory.CreateSolutionTemplate(templateLinks, dir, templateParams, solution.GetDirectoryName(),
                                                        solution.GetStartUpProject());

                string templateZipFilename = model.OutputDirectory.Combine(model.Name + ".zip");

                _logger.Log("Zipping Solution Template");
                _archiveService.ZipTemplate(dir, templateZipFilename);

                
                _installerCreationService.CreateInstaller(model, templateZipFilename);

                //_logger.Log("Creating Visual Studio Content package");
                //CreateContentPackage(model, templateZipFilename);
                _logger.Log("Solution Export Completed.");

                _messageBox.ShowSuccess("Solution Export Completed.");
            }
            catch (Exception ex)
            {
                _messageBox.ShowError(ex.ToString());
                _logger.Log(ex.ToString());
            }
        }
    }
}